package service

import (
	"context"
	pb "customer/api/customer"
	"customer/internal/biz"
	"customer/internal/data"
	"github.com/go-kratos/kratos/v2/middleware/auth/jwt"
	jwt4 "github.com/golang-jwt/jwt/v4"
	"log"
	"time"
)

type CustomerService struct {
	CD *data.CustomerData
	pb.UnimplementedCustomerServer
}

func NewCustomerService(cd *data.CustomerData) *CustomerService {
	return &CustomerService{
		CD: cd,
	}
}

func (s *CustomerService) GetVerifyCode(ctx context.Context, req *pb.GetVerifyCodeReq) (*pb.GetVerifyCodeResp, error) {
	//校验手机号
	pattern := `^(13\d|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18\d|19[0-35-9])\d{8}$`
	// 将正则表达式编译成一个正则对象（使用 PERL 语法）。
	// 该正则对象会采用“leftmost-first”模式。选择第一个匹配结果。
	// 如果正则表达式语法错误，则返回错误信息。
	//regexpattern := regexp.MustCompile(pattern)
	//
	//// 判断在 b（s、r）中能否找到 pattern 所匹配的字符串
	//if !regexpattern.MatchString(req.Telephone) {
	//	return &pb.GetVerifyCodeResp{
	//		Code:    1,
	//		Message: "手机格式错误",
	//	}, nil
	//}
	biz.Verification(pattern, req.Telephone)
	//二 通过验证码服务生成验证码（）复位键通信 grpc）
	//连接目标grpc服务器
	//conn, err := grpc.DialInsecure(context.Background(),
	//	grpc.WithEndpoint("localhost:9000"), //verifycode grpc service地址
	//)
	//if err != nil {
	//	return &pb.GetVerifyCodeResp{
	//		Code:    1,
	//		Message: "服务码验证不可用",
	//	}, nil
	//}
	//defer func() {
	//	_ = conn.Close()
	//}()
	//2发送获取验证码请求
	//client := verifyCode.NewVerifyCodeClient(conn)
	//ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	//defer cancel()
	//reply, err := client.GetVerifyCode(ctx, &verifyCode.GetVerifyCodeRequest{
	//	Length: 6,
	//	Type:   1,
	//})
	//if err != nil {
	//	return &pb.GetVerifyCodeResp{
	//		Code:    1,
	//		Message: "服务码接受错误" + err.Error(),
	//	}, nil
	//}
	addr := "localhost:9000"
	code, err := biz.GetVerifycode(context.Background(), addr)
	if err != nil {
		return &pb.GetVerifyCodeResp{
			Code:    1,
			Message: "服务码接受错误" + err.Error(),
		}, nil
	}
	//redis:临时存储
	const life = 60
	if err := s.CD.SetVerifyCode(req.Telephone, code, life); err != nil {
		return &pb.GetVerifyCodeResp{
			Code:    1,
			Message: "服务码存储错误（redis读取验证码错误）" + err.Error(),
		}, nil
	}
	return &pb.GetVerifyCodeResp{
		Code:           0,
		VerifyCode:     code,
		VerifyCodeTime: time.Now().Unix(),
		VerifyCodeLife: life,
	}, nil
}
func (s *CustomerService) Login(ctx context.Context, req *pb.LoginReq) (*pb.LoginResp, error) {
	//1校验电话和验证码
	//redis
	code := s.CD.GetVerifyCode(req.Telephone)
	log.Println(code)
	log.Println(req.VerifyCode)
	if code == "" || code != req.VerifyCode {
		return &pb.LoginResp{
			Code:    1,
			Message: "验证码不匹配",
		}, nil
	}

	//2判定电话号码是否注册 来获取顾客信息
	customer, err := s.CD.GetCustomerByTelephone(req.Telephone)
	if err != nil {
		return &pb.LoginResp{
			Code:    1,
			Message: "顾客信息获取错误",
		}, nil
	}
	//3设置token jwt-token

	token, err := s.CD.GenerateTokenAndSave(customer, biz.Duration*time.Second, biz.Secret)

	return &pb.LoginResp{
		Code:          0,
		Message:       "login.success",
		Token:         token,
		TokenCreateAt: time.Now().Unix(),
		TokenLife:     biz.Duration,
	}, nil
}
func (s *CustomerService) Logout(ctx context.Context, req *pb.LogoutReq) (*pb.LogoutResp, error) {
	//获取用户id
	claims, _ := jwt.FromContext(ctx)
	mapClaims := claims.(jwt4.MapClaims)
	//删除用户的token
	if err := s.CD.DelToken(mapClaims["jti"]); err != nil {
		return &pb.LogoutResp{
			Code:    1,
			Message: "删除token失败",
		}, err
	}
	return &pb.LogoutResp{
		Code:    0,
		Message: "logout success",
	}, nil
}
